package com.animatron.sample.client.tree;

import com.animatron.sample.client.tree.draw.TreeDrawer;
import com.animatron.sample.client.tree.node.Node;
import com.animatron.sample.client.tree.node.NodeHitResult;
import com.google.gwt.canvas.client.Canvas;
import com.google.gwt.canvas.dom.client.Context2d;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Widget;

public class TreeComponent extends Composite {

	private static TreeComponentUiBinder uiBinder = GWT.create(TreeComponentUiBinder.class);

	interface TreeComponentUiBinder extends UiBinder<Widget, TreeComponent> {
	}
	@UiField(provided = true)
	Canvas canvas;
	
	Node root = new Node();
	Node sellected = root;
	TreeDrawer treeDrawer;
	
	public TreeComponent()
	{
		getRoot().setName("/");
		canvas = Canvas.createIfSupported();
		initWidget(uiBinder.createAndBindUi(this));
		canvas.setPixelSize(300, 300);
		canvas.setCoordinateSpaceHeight(300);
		canvas.setCoordinateSpaceWidth(300);
		
		repaint();
	}

	public void repaint()
	{
		Context2d context2d = canvas.getContext2d();
		context2d.clearRect(0, 0, canvas.getCoordinateSpaceWidth(), canvas.getCoordinateSpaceHeight());
		treeDrawer = new TreeDrawer(context2d, getRoot(), getSellected(),16);
		treeDrawer.draw();
	}
	
	@SuppressWarnings("incomplete-switch")
	@UiHandler("canvas")
	void onCanvasClick(ClickEvent event)
	{
		if (treeDrawer != null)
		{
			NodeHitResult hitInfo = treeDrawer.nodeAt(event.getX(), event.getY());
			switch (hitInfo.getHitKind()) {
			case CAPTION:
				setSellected(hitInfo.getNode());
				repaint();
				break;
			case PLUSMINUS:
				hitInfo.getNode().toggle();
				repaint();
				break;
			}
		}
	}

	public Node getRoot()
	{
		return root;
	}

	public Node getSellected()
	{
		if (sellected == null)
			return getRoot();
		return sellected;
	}

	public void setSellected(Node sellected)
	{
		this.sellected = sellected;
	}

}
